package com.ayoka.parenting.utils;

import android.content.Context;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;

import java.io.IOException;
import java.util.Observable;


/**
 * 播放管理类，单例模式
 */

public class MediaManager extends Observable implements MediaPlayer.OnBufferingUpdateListener, MediaPlayer.OnCompletionListener, MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener, MediaPlayer.OnSeekCompleteListener, MediaPlayer.OnInfoListener {
    /**
     * 规定开始音乐、暂停音乐、结束音乐的标志
     */
    public static final int RELEASE = -1;
    public static final int STOP = 0;
    public static final int PLAY = 1;

    public static final float DEFAULT_VOLUME = 0.8f;

    private volatile static MediaManager instance;

    //用于播放音乐等媒体资源
    private volatile static MediaPlayer mediaPlayer;

    // 标志判断播放歌曲是否是停止之后重新播放，还是继续播放
    private int status = RELEASE;
    // 默认音量
    private float volume = DEFAULT_VOLUME;
    // 消息队列
    private Handler handler;

    private OperatorResultBean operatorResultBean;

    private MediaManager() {
        mediaPlayer = new MediaPlayer();
        handler = new Handler(Looper.getMainLooper());
        operatorResultBean = new OperatorResultBean();
    }

    private Runnable task = new Runnable() {
        @Override
        public void run() {
            if (mediaPlayer != null) {
                operatorResultBean.operation = OperatorResultBean.ON_PROGRESS_UPDATE;
                operatorResultBean.operatorValue = mediaPlayer.getCurrentPosition();
                setChanged();
                notifyObservers(operatorResultBean);
            }
            handler.postDelayed(this, 250);
        }
    };

    public static MediaManager getInstance() {
        if (instance == null) {
            synchronized (MediaManager.class) {
                if (instance == null) {
                    instance = new MediaManager();
                }
            }
        }
        return instance;
    }

    public void setMediaDataSource(String filepath) {
        if (mediaPlayer == null) {
            mediaPlayer = new MediaPlayer();
        } else {
            mediaPlayer.reset();
        }
        try {
            mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
            mediaPlayer.setDataSource(filepath);
            mediaPlayer.prepareAsync();
            mediaPlayer.setOnPreparedListener(this);
            mediaPlayer.setOnBufferingUpdateListener(this);
            mediaPlayer.setOnInfoListener(this);
            mediaPlayer.setOnSeekCompleteListener(this);
            mediaPlayer.setOnCompletionListener(this);
            mediaPlayer.setOnErrorListener(this);
            operatorResultBean.operation = OperatorResultBean.ON_MEDIA_PLAYER_STOP;
            setChanged();
            notifyObservers(operatorResultBean);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void start() {
        try {
            handler.removeCallbacks(task);
            handler.post(task);
            if (mediaPlayer != null) {
                mediaPlayer.start();
                mediaPlayer.setVolume(volume, volume);
                status = PLAY;
            }
            operatorResultBean.operation = OperatorResultBean.ON_MEDIA_PLAYER_START;
            setChanged();
            notifyObservers(operatorResultBean);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void pause() {
        try {
            handler.removeCallbacks(task);
            if (mediaPlayer != null && status == PLAY) {
                mediaPlayer.pause();
                status = STOP;
            }
            operatorResultBean.operation = OperatorResultBean.ON_MEDIA_PLAYER_STOP;
            setChanged();
            notifyObservers(operatorResultBean);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void seekTo(int process) {
        try {
            //播放器不为空，并且正在播放
            if (mediaPlayer != null) {
                mediaPlayer.seekTo(process);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void release() {
        try {
            status = RELEASE;
            handler.removeCallbacks(task);
            if (mediaPlayer != null) {
                try {
                    mediaPlayer.setOnErrorListener(null);
                    mediaPlayer.setOnInfoListener(null);
                    mediaPlayer.setOnPreparedListener(null);
                    mediaPlayer.stop();
                    mediaPlayer.release();
                    mediaPlayer = null;
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void setVolume(float volume) {
        try {
            this.volume = volume;
            if (mediaPlayer == null) {
                return;
            } else {
                mediaPlayer.setVolume(volume, volume);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public int getPlayStatus() {
        return status;
    }

    @Override
    public boolean onError(MediaPlayer mp, int what, int extra) {
        Log.d("MediaManager", "MEDIA_ERROR what = " + what + " extra = " + extra);
        release();
        // 设置错误监听或者onError方法返回false，就调用OnCompletionListener的onCompletion方法。
        return true;
    }

    @Override
    public void onBufferingUpdate(MediaPlayer mp, int percent) {
        Log.d("MediaManager", "onBufferingUpdate");
        operatorResultBean.operation = OperatorResultBean.ON_BUFFERING_UPDATE;
        operatorResultBean.operatorValue = percent;
        setChanged();
        notifyObservers(operatorResultBean);
    }

    @Override
    public void onCompletion(MediaPlayer mediaPlayer) {
        Log.d("MediaManager", "onMediaPlayCompletion");
        status = STOP;
        handler.removeCallbacks(task);
        operatorResultBean.operation = OperatorResultBean.ON_MEDIA_PLAYER_COMPLETION;
        setChanged();
        notifyObservers(operatorResultBean);
    }

    @Override
    public void onPrepared(MediaPlayer mediaPlayer) {
        Log.d("MediaManager", "onPrepared");
        status = STOP;
        operatorResultBean.operation = OperatorResultBean.GET_MEDIA_DURATION;
        operatorResultBean.operatorValue = mediaPlayer.getDuration();
        setChanged();
        notifyObservers(operatorResultBean);
    }

    @Override
    public boolean onInfo(MediaPlayer mediaPlayer, int what, int extra) {
        Log.d("MediaManager", "onInfo");
        switch (what) {
            case MediaPlayer.MEDIA_INFO_BUFFERING_START:
                operatorResultBean.operation = OperatorResultBean.ON_BUFFERING_START;
                setChanged();
                notifyObservers(operatorResultBean);
                break;
            case MediaPlayer.MEDIA_INFO_BUFFERING_END:
                // 缓存完成，继续播放
                operatorResultBean.operation = OperatorResultBean.ON_BUFFERING_END;
                setChanged();
                notifyObservers(operatorResultBean);
                break;
        }
        return false;
    }

    @Override
    public void onSeekComplete(MediaPlayer mediaPlayer) {
        Log.d("MediaManager", "onSeekComplete");
        handler.removeCallbacks(task);
        handler.post(task);
        mediaPlayer.start();
        status = PLAY;
        operatorResultBean.operation = OperatorResultBean.ON_MEDIA_PLAYER_START;
        setChanged();
        notifyObservers(operatorResultBean);
    }


    public static class OperatorResultBean{
        public static final int ON_PROGRESS_UPDATE = 0;
        public static final int ON_MEDIA_PLAYER_STOP = 1;
        public static final int ON_MEDIA_PLAYER_START = 2;
        public static final int ON_MEDIA_PLAYER_COMPLETION =4;
        public static final int GET_MEDIA_DURATION = 5;
        public static final int ON_BUFFERING_UPDATE = 3;
        public static final int ON_BUFFERING_START = 6;
        public static final int ON_BUFFERING_END = 7;

        public int operation;
        public Object operatorValue;
    }
}